const Pending = 'pending'
const Resolved = 'resolved'
const Rejected = 'rejected'
const resolvepromise = (promise2, x, resolve, reject) => {
  if (promise2 === x) {
    return reject(new TypeError('不能返回自身'))
  }
  if (typeof x === 'object' && typeof x !== null || typeof x === 'function') {
    //由于测试的时候即调用成功，也调用失败resolve(),reject()
    try {
      let then = x.then
      if (typeof then === 'function') {//是一个promise
        then.call(x, y => {
          resolvepromise(promise2, y, resolve, reject)//什么意思就是说这个，resolve可能继续返回一个promise，所以想递归不断得到一个普通值后再去返回

        }, r => {
          reject(r)
        })//这里为什么是x

      } else {
        resolve(x)//这里就是说这个x亦可能是普通值then里面返回一个普通值自然，调用promise2的一个resolve(x)
      }

    } catch (error) {
      reject(error)
    }

  }

}
class Promise {

  constructor(executor) {
    this.status = 'pending'
    this.value = undefined
    this.reason = undefined
    this.onResolvecallbacks = []
    this.onRejectecallbacks = []

    let resolve = (value) => {
      if (this.status === Pending) {
        this.value = value
        this.status = Resolved
        this.onResolvecallbacks.forEach(fn => fn())

      }

    }
    let reject = (reason) => {
      if (this.status === Pending) {
        this.reason = reason
        this.status = Rejected
        this.onRejectecallbacks.forEach(fn => fn())
      }


    }

    try {
      executor(resolve, reject)
    } catch (error) {
      reject(error)
    }

  }


  then(onsuccess, onreject) {
    let promise2 = new Promise((resolve, reject) => {
      if (this.status === Resolved) {
        setTimeout(() => {
          try {
            let x = onsuccess(this.value)//普通值，这里是想来获取第一次的then的成功函数返回的结果
            resolvepromise(promise2, x, resolve, reject)
          } catch (error) {
            reject(error)
          }

        }, 0);

      }
      if (this.status === Rejected) {
        setTimeout(() => {
          try {
            let x = onreject(this.reason)
            resolvepromise(promise2, x, resolve, reject)
          } catch (error) {
            reject(error)
          }

        }, 0);

      }
      if (this.status === Pending) {
        this.onResolvecallbacks.push(() => {
          setTimeout(() => {
            try {
              let x = onsuccess(this.value)
              resolvepromise(promise2, x, resolve, reject)
            } catch (error) {
              reject(error)
            }
          }, 0);

        })
        this.onRejectecallbacks.push(() => {
          setTimeout(() => {
            try {
              let x = onreject(this.reason)
              resolvepromise(promise2, x, resolve, reject)
            } catch (error) {
              reject(error)
            }

          }, 0);

        })
      }
    })
    return promise2


  }
}